package com.colorlight.cloud.complete.entity.po;

import com.colorlight.cloud.complete.entity.enumerate.*;
import com.colorlight.cloud.gateway.api.message.constraint.basics.object.Trans;
import com.colorlight.cloud.gateway.api.message.constraint.schedule.ScheduleActions;
import com.colorlight.iot.proto.complete.entity.CompleteEntity;
import com.google.protobuf.ByteString;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.colorlight.cloud.common.constants.CommonConstants.GSON;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Slf4j
public class CommandSchedule implements Trans<CommandSchedule, CompleteEntity.CommandSchedule> {
	
	
	/**
	 * 限制时间 指定日期模式 多段，指定周期模式一段
	 * 指令类型
	 * 对应具体的排程数据，为pb
	 * 指令唯一ID,可以是时间戳、uuid等
	 * 时间段集合
	 * 要执行的屏体uuid
	 * 指定日期模式：1是指定日期模式，2是指定周期模式
	 * 高级控制序列号，判断属于哪个高级控制
	 */
	private List<LimitDate> limitDate;
	private Integer weekday;
	private ScheduleTypeInnerStruct type;
	private String scheduleActions;
	private Long seq;
	private List<LimitTime> limitTime;
	private String uuid;
	private RealTimeMode mode;
	private Long commandSeq;
	
	
	@Override
	public CompleteEntity.CommandSchedule toProto() {
		String scheduleActions = this.getScheduleActions();
		Class<? extends ScheduleActions> aClass = this.getType().getAClass();
		
		ScheduleActions object = GSON.fromJson(scheduleActions, aClass);
		CompleteEntity.CommandSchedule.Builder builder = CompleteEntity.CommandSchedule.newBuilder();
		if (Objects.nonNull(limitDate) && limitDate.size() != 0) {
			builder.addAllLimitDate(limitDate.stream().map(LimitDate::toProto).collect(Collectors.toList()));
		}
		if (Objects.nonNull(weekday)) {
			builder.setWeekday(this.getWeekday());
		}
		if (Objects.nonNull(type)) {
			builder.setType(CompleteEntity.ScheduleTypeStruct.valueOf(this.getType().getId()));
		}
		if (Objects.nonNull(scheduleActions)) {
			builder.setValue(object.objectConvertBytes());
		}
		if (Objects.nonNull(seq)) {
			builder.setSeq(this.getSeq());
		}
		if (Objects.nonNull(limitTime)) {
			builder.addAllLimitTime(this.getLimitTime().stream().map(LimitTime::toProto).collect(Collectors.toList()));
		}
		if (Objects.nonNull(uuid)) {
			builder.setUuid(this.getUuid());
		}
		if (Objects.nonNull(mode)) {
			builder.setMode(this.getMode().getValue());
		}
		if (Objects.nonNull(commandSeq)) {
			builder.setCommandSeq(this.getCommandSeq());
		}
		return builder.build();
	}
	
	@Override
	public CommandSchedule formProto(CompleteEntity.CommandSchedule commandSchedule) {
		this.setLimitDate(commandSchedule.getLimitDateList().stream().map(e -> new LimitDate().formProto(e)).collect(Collectors.toList()));
		this.setWeekday(commandSchedule.getWeekday());
		ScheduleTypeInnerStruct scheduleTypeStruct = ScheduleTypeInnerStruct.getScheduleTypeInnerStruct(commandSchedule.getType());
		this.setType(scheduleTypeStruct);
		ByteString value = commandSchedule.getValue();
		Class<? extends ScheduleActions> aClass = this.getType().getAClass();
		ScheduleActions scheduleActions = null;
		try {
			scheduleActions = aClass.getDeclaredConstructor().newInstance();
		} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			log.error("", e);
		}
		assert scheduleActions != null;
		scheduleActions.byteConvertObject(value);
		String json = GSON.toJson(scheduleActions);
		this.setScheduleActions(json);
		this.setSeq(commandSchedule.getSeq());
		this.setLimitTime(commandSchedule.getLimitTimeList().stream().map(e -> new LimitTime().formProto(e)).collect(Collectors.toList()));
		this.setUuid(commandSchedule.getUuid());
		this.setMode(RealTimeMode.getRealTimeMode(commandSchedule.getMode()));
		this.setCommandSeq(commandSchedule.getCommandSeq());
		return this;
	}
}

